package bookez.model.service.impl;

import java.util.ArrayList;
import java.util.List;

import bookez.model.businessobject.Route;
import bookez.model.dao.RouteDao;
import bookez.model.exception.BusinessLogicLayerException;
import bookez.model.exception.DataAccessLayerException;
import bookez.model.exception.DuplicateValueException;
import bookez.model.exception.RouteExistingException;
import bookez.model.service.GenericService;
import bookez.model.service.RouteService;

public class CachedRouteServiceImpl extends GenericService<RouteDao> implements RouteService {

	@Override
	public boolean saveRoute(Route route) throws BusinessLogicLayerException {
		// TODO Auto-generated method stub
		makeCacheReady();
		
		boolean result = false;
		
		boolean isCached = isCached( route );
		
		if( isCached ) {
			result = isCached;
		}
		
		else {
			try {
				getDao().create( route );
				getCache().add( route );
				result = true;
			}//end try

			catch( DuplicateValueException dve ) {
				throw new RouteExistingException( dve );
			}//end catch 
			
			catch( DataAccessLayerException dalEx ) {
				throw new BusinessLogicLayerException( dalEx );
			}//end catch
		}//end else
		
		return result;
	}//end method saveRoute

	@Override
	public List<Route> getAllRoute() throws BusinessLogicLayerException {
		// TODO Auto-generated method stub
		makeCacheReady();
		return getCache();
	}//end method getAllRoute

	@Override
	public List<Route> getRouteByFromCity(String fromCity)
			throws BusinessLogicLayerException {
		// TODO Auto-generated method stub
		makeCacheReady();
		
		List<Route> result = new ArrayList<Route>();
		
		for( Route route : getCache() ) {
			if( route.getFromCity().equals( fromCity ) ) {
				result.add( route );
			}//end if: matched fromCity
		}//end for
		
		return result;
	}//end method getRouteByFromCity

	@Override
	public List<Route> getRouteByToCity(String toCity)
			throws BusinessLogicLayerException {
		// TODO Auto-generated method stub
		return null;
	}//end method getRouteByToCity
	
	private boolean isCached( Route route ) {
		boolean isCached = false;
		
		for( Route cachedRoute : getCache() ) {
			if( cachedRoute.equals( route ) ) {
				route.setId( cachedRoute.getId() );
				return true;			
			}
		}//end for
		
		return isCached;
	}//end method isExisting
	
	private void makeCacheReady() throws BusinessLogicLayerException {
		if( getCache() == null ) {
			buildCache();
		}
	}//end method makeCacheReady
	
	private void buildCache() throws BusinessLogicLayerException {
		
		try {
			List<Route> routes = getDao().findAll();
			setCache( routes );
		}
		catch ( DataAccessLayerException dalEx ) {
			throw new BusinessLogicLayerException( "Cannot build cache.", dalEx );
		}//end method
		
	}//end method buildCache
	
	private List<Route> getCache() { return this.cache; }
	private void setCache( List<Route> value ) { this.cache = value; }
	
	private List<Route> cache;

}//end class CachedRouteServiceImpl
